export default class CRS {
  // R = 6371000;
  R = 6378137;
  constructor() {}

  // 获取地球半径
  getEARTHRAD() {
    return this.R;
  }

  // 获取这一层级的瓦片数
  scale(zoom) {
    return 256 * Math.pow(2, zoom);
  }

  // 获取分辨率
  getResolution(zoom) {
    // 地球周长
    const EARTH_PERIMETER = 2 * Math.PI * this.R;
    return EARTH_PERIMETER / this.scale(zoom);
  }

  scale(zoom) {
		return 256 * Math.pow(2, zoom);
	}

	// @method zoom(scale: Number): Number
	// Inverse of `scale()`, returns the zoom level corresponding to a scale
	// factor of `scale`.
	zoom(scale) {
		return Math.log(scale / 256) / Math.LN2;
	}
  // 利用余弦近似的球面定律计算两个地理点之间的距离
  distance(latlng1, latlng2, isfUnit = false) {
    const rad = Math.PI / 180,
      lat1 = latlng1.lat * rad,
      lat2 = latlng2.lat * rad,
      sinDLat = Math.sin(((latlng2.lat - latlng1.lat) * rad) / 2),
      sinDLon = Math.sin(((latlng2.lng - latlng1.lng) * rad) / 2),
      a =
        sinDLat * sinDLat + Math.cos(lat1) * Math.cos(lat2) * sinDLon * sinDLon,
      c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
    const value = this.R * c;
    if (isfUnit) {
      if (value > 1000) {
        return (value / 1000).toFixed(1) + "千米";
      } else {
        return parseInt(value) + "米";
      }
    } else {
      return value;
    }
  }

  computeSignedArea(path) {
    //传入path：[{lat:,lng:},{lat:,lng:}]
    let _this = this;
    let radius = 6371009;
    let len = path.length;
    if (len < 3) return 0;
    let total = 0;
    let prev = path[len - 1];
    let prevTanLat = Math.tan((Math.PI / 2 - (prev[1] / 180) * Math.PI) / 2);
    let prevLng = (prev[0] / 180) * Math.PI;
    for (let i in path) {
      let tanLat = Math.tan((Math.PI / 2 - (path[i][1] / 180) * Math.PI) / 2);
      let lng = (path[i][0] / 180) * Math.PI;
      total += this.polarTriangleArea(tanLat, lng, prevTanLat, prevLng);
      prevTanLat = tanLat;
      prevLng = lng;
    }
    let area = Math.abs(total * (radius * radius));
    let areaResult = "";
    if (area > 100 * 1000) {
      areaResult = (area / 1000 / 1000).toFixed(2) + "km²";
    } else {
      areaResult = area.toFixed(2) + "m²";
    }
    return areaResult;
  }
  polarTriangleArea(tan1, lng1, tan2, lng2) {
    let deltaLng = lng1 - lng2;
    let t = tan1 * tan2;
    return 2 * Math.atan2(t * Math.sin(deltaLng), 1 + t * Math.cos(deltaLng));
  }

  areaCenter(coordinates) {
    let maxLng = coordinates[0][0];
    let minLng = coordinates[0][0];
    let maxLat = coordinates[0][1];
    let minLat = coordinates[0][1];
    let tempPoint;
    for (let i = coordinates.length - 1; i >= 0; i--) {
      tempPoint = coordinates[i];
      if (tempPoint[0] > maxLng) maxLng = tempPoint[0];
      if (tempPoint[0] < minLng) minLng = tempPoint[0];
      if (tempPoint[1] > maxLat) maxLat = tempPoint[1];
      if (tempPoint[1] < minLat) minLat = tempPoint[1];
    }
    const cenLng = (parseFloat(maxLng) + parseFloat(minLng)) / 2;
    const cenLat = (parseFloat(maxLat) + parseFloat(minLat)) / 2;

    return {
      maxLng,
      minLng,
      maxLat,
      minLat,
      cenLng,
      cenLat,
    };
  }
}
